home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / GNU / gnuplot.lha / gnuplot / src / plot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-28  |  13.0 KB  |  499 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: plot.c%v 3.50.1.8 1993/07/27 05:37:15 woo Exp $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - plot.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted, 
  12.  * provided that the above copyright notice appear in all copies and 
  13.  * that both that copyright notice and this permission notice appear 
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the modified code.  Modifications are to be distributed 
  18.  * as patches to released version.
  19.  *  
  20.  * This software is provided "as is" without express or implied warranty.
  21.  * 
  22.  *
  23.  * AUTHORS
  24.  * 
  25.  *   Original Software:
  26.  *     Thomas Williams,  Colin Kelley.
  27.  * 
  28.  *   Gnuplot 2.0 additions:
  29.  *       Russell Lang, Dave Kotz, John Campbell.
  30.  *
  31.  *   Gnuplot 3.0 additions:
  32.  *       Gershon Elber and many others.
  33.  * 
  34.  * There is a mailing list for gnuplot users. Note, however, that the
  35.  * newsgroup 
  36.  *    comp.graphics.gnuplot 
  37.  * is identical to the mailing list (they
  38.  * both carry the same set of messages). We prefer that you read the
  39.  * messages through that newsgroup, to subscribing to the mailing list.
  40.  * (If you can read that newsgroup, and are already on the mailing list,
  41.  * please send a message info-gnuplot-request@dartmouth.edu, asking to be
  42.  * removed from the mailing list.)
  43.  *
  44.  * The address for mailing to list members is
  45.  *       info-gnuplot@dartmouth.edu
  46.  * and for mailing administrative requests is 
  47.  *       info-gnuplot-request@dartmouth.edu
  48.  * The mailing list for bug reports is 
  49.  *       bug-gnuplot@dartmouth.edu
  50.  * The list of those interested in beta-test versions is
  51.  *       info-gnuplot-beta@dartmouth.edu
  52.  */
  53.  
  54. #include <stdio.h>
  55. #include <setjmp.h>
  56. #include <signal.h>
  57. #ifdef XPG3_LOCALE
  58. #include <locale.h>
  59. #endif
  60. #include "plot.h"
  61. #include "fit.h"
  62. #include "setshow.h"
  63. #if defined(MSDOS) || defined(DOS386)
  64. #include <io.h>
  65. #endif
  66. #ifdef vms
  67. #include <unixio.h>
  68. #include <smgdef.h>
  69. extern int vms_vkid;
  70. extern smg$create_virtual_keyboard();
  71. unsigned int status[2] = {1, 0};
  72. #endif
  73. #ifdef AMIGA_SC_6_1
  74. #include <proto/dos.h>
  75. #endif
  76.  
  77. #ifdef _Windows
  78. #include <windows.h>
  79. #ifndef SIGINT
  80. #define SIGINT 2    /* for MSC */
  81. #endif
  82. #else
  83. # ifdef __TURBOC__
  84. # include <graphics.h>
  85. # endif
  86. #endif
  87.  
  88. #ifndef AMIGA_SC_6_1
  89. extern char *getenv(),*strcat(),*strcpy(),*strncpy();
  90. #endif /* !AMIGA_SC_6_1 */
  91.  
  92. extern char input_line[];
  93. extern int c_token;
  94. extern FILE *outfile;
  95. extern int term;
  96.  
  97. TBOOLEAN interactive = TRUE;    /* FALSE if stdin not a terminal */
  98. TBOOLEAN noinputfiles = TRUE;    /* FALSE if there are script files */
  99. char *infile_name = NULL;    /* name of command file; NULL if terminal */
  100.  
  101. #ifndef STDOUT
  102. #define STDOUT 1
  103. #endif
  104.  
  105. #ifdef _Windows
  106. jmp_buf far env;
  107. #else
  108. jmp_buf env;
  109. #endif
  110.  
  111. struct value *Ginteger(),*Gcomplex();
  112.  
  113.  
  114. extern f_push(),f_pushc(),f_pushd1(),f_pushd2(),f_pushd(),f_call(),f_calln(),
  115.     f_lnot(),f_bnot(),f_uminus(),f_lor(),f_land(),f_bor(),f_xor(),
  116.     f_band(),f_eq(),f_ne(),f_gt(),f_lt(),
  117.     f_ge(),f_le(),f_plus(),f_minus(),f_mult(),f_div(),f_mod(),f_power(),
  118.     f_factorial(),f_bool(),f_jump(),f_jumpz(),f_jumpnz(),f_jtern();
  119.  
  120. extern f_real(),f_imag(),f_arg(),f_conjg(),f_sin(),f_cos(),f_tan(),f_asin(),
  121.     f_acos(),f_atan(),f_sinh(),f_cosh(),f_tanh(),f_int(),f_abs(),f_sgn(),
  122.     f_sqrt(),f_exp(),f_log10(),f_log(),f_besj0(),f_besj1(),f_besy0(),f_besy1(),
  123.     f_erf(), f_erfc(), f_gamma(), f_lgamma(), f_ibeta(), f_igamma(), f_rand(),
  124.     f_floor(),f_ceil(),
  125.     f_normal(), f_inverse_erf(), f_inverse_normal();   /* XXX - JG */
  126.  
  127.  
  128. struct ft_entry GPFAR ft[] = {    /* built-in function table */
  129.  
  130. /* internal functions: */
  131.     {"push", f_push},    {"pushc", f_pushc},
  132.     {"pushd1", f_pushd1},    {"pushd2", f_pushd2},    {"pushd", f_pushd},
  133.     {"call", f_call},    {"calln", f_calln},    {"lnot", f_lnot},
  134.     {"bnot", f_bnot},    {"uminus", f_uminus},    {"lor", f_lor},
  135.     {"land", f_land},    {"bor", f_bor},        {"xor", f_xor},
  136.     {"band", f_band},    {"eq", f_eq},        {"ne", f_ne},
  137.     {"gt", f_gt},        {"lt", f_lt},        {"ge", f_ge},
  138.     {"le", f_le},        {"plus", f_plus},    {"minus", f_minus},
  139.     {"mult", f_mult},    {"div", f_div},        {"mod", f_mod},
  140.     {"power", f_power}, {"factorial", f_factorial},
  141.     {"bool", f_bool},    {"jump", f_jump},    {"jumpz", f_jumpz},
  142.     {"jumpnz",f_jumpnz},{"jtern", f_jtern},
  143.  
  144. /* standard functions: */
  145.     {"real", f_real},    {"imag", f_imag},    {"arg", f_arg},
  146.     {"conjg", f_conjg}, {"sin", f_sin},        {"cos", f_cos},
  147.     {"tan", f_tan},        {"asin", f_asin},    {"acos", f_acos},
  148.     {"atan", f_atan},    {"sinh", f_sinh},    {"cosh", f_cosh},
  149.     {"tanh", f_tanh},    {"int", f_int},        {"abs", f_abs},
  150.     {"sgn", f_sgn},        {"sqrt", f_sqrt},    {"exp", f_exp},
  151.     {"log10", f_log10},    {"log", f_log},        {"besj0", f_besj0},
  152.     {"besj1", f_besj1},    {"besy0", f_besy0},    {"besy1", f_besy1},
  153.         {"erf", f_erf},         {"erfc", f_erfc},       {"gamma", f_gamma},     {"lgamma", f_lgamma},
  154.         {"ibeta", f_ibeta},     {"igamma", f_igamma},   {"rand", f_rand},
  155.         {"floor", f_floor},     {"ceil", f_ceil},
  156.  
  157.     {"norm",        f_normal},              /* XXX-JG */
  158.     {"inverf",      f_inverse_erf},         /* XXX-JG */
  159.     {"invnorm",     f_inverse_normal},      /* XXX-JG */
  160.  
  161.     {NULL, NULL}
  162. };
  163.  
  164. static struct udvt_entry udv_pi = {NULL, "pi",FALSE};
  165.                                     /* first in linked list */
  166. struct udvt_entry *first_udv = &udv_pi;
  167. struct udft_entry *first_udf = NULL;
  168.  
  169.  
  170.  
  171. #ifdef vms
  172.  
  173. #define HOME "sys$login:"
  174.  
  175. #else /* vms */
  176. #if defined(MSDOS) ||  defined(AMIGA_AC_5) || defined(AMIGA_SC_6_1) || defined(ATARI) || defined(OS2) || defined(_Windows) || defined(DOS386)
  177.  
  178. #define HOME "GNUPLOT"
  179.  
  180. #else /* MSDOS || AMIGA || ATARI || OS2 || _Windows || defined(DOS386)*/
  181.  
  182. #define HOME "HOME"
  183.  
  184. #endif /* MSDOS || AMIGA || ATARI || OS2 || _Windows || defined(DOS386)*/
  185. #endif /* vms */
  186.  
  187. #if defined(unix) || defined(AMIGA_AC_5) || defined(AMIGA_SC_6_1)
  188. #define PLOTRC ".gnuplot"
  189. #else /* AMIGA || unix */
  190. #define PLOTRC "gnuplot.ini"
  191. #endif /* AMIGA || unix */
  192.  
  193. #if defined (__TURBOC__) || defined (__PUREC__)
  194. void tc_interrupt()
  195. #else
  196. #ifdef __ZTC__
  197. void ztc_interrupt()
  198. #else
  199. #if defined( _CRAY ) || defined( sgi ) || defined( __alpha )
  200. void inter(an_int)
  201. int an_int;
  202. #else
  203. #if defined( NEXT ) || defined( OS2 ) || defined( VMS )
  204. void inter(int an_int)
  205. #else
  206. #ifdef sgi
  207. void inter(int sig, int code, struct sigcontext *sc)
  208. #else
  209. #if defined(SOLARIS)
  210. void inter()
  211. #else
  212. inter()
  213. #endif
  214. #endif
  215. #endif
  216. #endif
  217. #endif
  218. #endif
  219. {
  220. #if defined (MSDOS) || defined(_Windows) || (defined (ATARI) && defined(__PUREC__)) || defined(DOS386)
  221. #if defined (__TURBOC__) || defined (__PUREC__)
  222. #ifndef DOSX286
  223.     (void) signal(SIGINT, tc_interrupt);
  224. #endif
  225. #else
  226. #ifdef __ZTC__
  227.    (void) signal(SIGINT, ztc_interrupt);
  228. #else
  229. #ifdef __EMX__
  230.     (void) signal(SIGINT, (void *)inter);
  231. #else
  232. #ifdef DJGPP
  233.     (void) signal(SIGINT, (SignalHandler)inter);
  234. #else
  235. #if defined __MSC__
  236.     (void) signal(SIGINT, inter);
  237. #endif    /* __MSC__ */
  238.  
  239. #endif    /* DJGPP */
  240. #endif  /* __EMX__ */
  241. #endif    /* ZTC */
  242. #endif  /* __TURBOC__ */
  243.  
  244. #else  /* MSDOS */
  245. #ifdef OS2
  246.     (void) signal(an_int, SIG_ACK);
  247. #else
  248.     (void) signal(SIGINT, inter);
  249. #endif  /* OS2 */
  250. #endif  /* MSDOS */
  251. #ifndef DOSX286
  252.     (void) signal(SIGFPE, SIG_DFL);    /* turn off FPE trapping */
  253. #endif
  254.     if (term && term_init)
  255.         (*term_tbl[term].text)();    /* hopefully reset text mode */
  256.     (void) fflush(outfile);
  257.     (void) putc('\n',stderr);
  258.     longjmp(env, TRUE);        /* return to prompt */
  259. }
  260.  
  261.  
  262. #ifdef _Windows
  263. gnu_main(argc, argv)
  264. #else
  265. main(argc, argv)
  266. #endif
  267.     int argc;
  268.     char **argv;
  269. {
  270. #ifdef XPG3_LOCALE
  271.     (void) setlocale(LC_CTYPE, "");
  272. #endif
  273. /* Register the Borland Graphics Interface drivers. If they have been */
  274. /* included by the linker.                                            */
  275.  
  276. #ifndef DOSX286
  277. #ifndef _Windows
  278. #if defined (__TURBOC__) && defined (MSDOS)
  279. registerfarbgidriver(EGAVGA_driver_far);
  280. registerfarbgidriver(CGA_driver_far);
  281. registerfarbgidriver(Herc_driver_far);
  282. registerfarbgidriver(ATT_driver_far);
  283. # endif
  284. #endif
  285. #endif
  286. #ifdef X11
  287.      { int n = X11_args(argc, argv); argv += n; argc -= n; }
  288. #endif 
  289.  
  290. #ifdef apollo
  291.     apollo_pfm_catch();
  292. #endif
  293.  
  294.     setbuf(stderr,(char *)NULL);
  295. #ifdef UNIX
  296.     setlinebuf(stdout);
  297. #endif
  298.     outfile = stdout;
  299.     (void) Gcomplex(&udv_pi.udv_value, Pi, 0.0);
  300.  
  301.      interactive = FALSE;
  302.      init_terminal();        /* can set term type if it likes */
  303.  
  304. #ifdef AMIGA_SC_6_1
  305.      if (IsInteractive(Input()) == DOSTRUE) interactive = TRUE;
  306.      else interactive = FALSE;
  307. #else
  308. #if defined(__MSC__) && defined(_Windows)
  309.      interactive = TRUE;
  310. #else
  311.      interactive = isatty(fileno(stdin));
  312. #endif
  313. #endif
  314.      if (argc > 1)
  315.       interactive = noinputfiles = FALSE;
  316.      else
  317.       noinputfiles = TRUE;
  318.  
  319.      if (interactive)
  320.       show_version();
  321. #ifdef vms   /* initialise screen management routines for command recall */
  322.           if (status[1] = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL)
  323.                done(status[1]);
  324. #endif
  325.  
  326.     if (!setjmp(env)) {
  327.         /* first time */
  328.         interrupt_setup();
  329.         load_rcfile();
  330.         init_fit ();    /* Initialization of fitting module */
  331.  
  332.         if (interactive && term != 0)    /* not unknown */
  333.          fprintf(stderr, "\nTerminal type set to '%s'\n", 
  334.                 term_tbl[term].name);
  335.     } else {    
  336.         /* come back here from int_error() */
  337. #ifdef AMIGA_SC_6_1
  338.         (void) rawcon(0);
  339. #endif
  340.         load_file_error();    /* if we were in load_file(), cleanup */
  341. #ifdef _Windows
  342.     SetCursor(LoadCursor((HINSTANCE)NULL, IDC_ARROW));
  343. #endif
  344. #ifdef vms
  345.         /* after catching interrupt */
  346.         /* VAX stuffs up stdout on SIGINT while writing to stdout,
  347.           so reopen stdout. */
  348.         if (outfile == stdout) {
  349.            if ( (stdout = freopen("SYS$OUTPUT","w",stdout))  == NULL) {
  350.               /* couldn't reopen it so try opening it instead */
  351.               if ( (stdout = fopen("SYS$OUTPUT","w"))  == NULL) {
  352.                  /* don't use int_error here - causes infinite loop! */
  353.                  fprintf(stderr,"Error opening SYS$OUTPUT as stdout\n");
  354.               }
  355.            }
  356.            outfile = stdout;
  357.         }
  358. #endif                    /* VMS */
  359.         if (!interactive && !noinputfiles) {
  360.             if (term && term_init)
  361.                 (*term_tbl[term].reset)();
  362. #ifdef vms
  363.             vms_reset();
  364. #endif
  365.             return(IO_ERROR);    /* exit on non-interactive error */
  366.          }
  367.     }
  368.  
  369.      if (argc > 1) {
  370.         /* load filenames given as arguments */
  371.         while (--argc > 0) {
  372.            ++argv;
  373.            c_token = NO_CARET; /* in case of file not found */
  374.            load_file(fopen(*argv,"r"), *argv);    
  375.         }
  376.     } else {
  377.         /* take commands from stdin */
  378.         while(!com_line());
  379.     }
  380.  
  381.     if (term && term_init)
  382.         (*term_tbl[term].reset)();
  383. #ifdef vms
  384.     vms_reset();
  385. #endif
  386.     return(IO_SUCCESS);
  387. }
  388.  
  389. #if defined(ATARI) && defined(__PUREC__)
  390. #include <math.h>
  391. int purec_matherr(struct exception *e)
  392. {    char *c;
  393.     switch (e->type) {
  394.         case DOMAIN:    c = "domain error"; break;
  395.         case SING  :    c = "argument singularity"; break;
  396.         case OVERFLOW:  c = "overflow range"; break;
  397.         case UNDERFLOW: c = "underflow range"; break;
  398.         default:        c = "(unknown error"; break;
  399.     }
  400.     fprintf(stderr, "math exception : %s\n", c);
  401.     fprintf(stderr, "    name : %s\n", e->name);
  402.     fprintf(stderr, "    arg 1: %e\n", e->arg1);
  403.     fprintf(stderr, "    arg 2: %e\n", e->arg2);
  404.     fprintf(stderr, "    ret  : %e\n", e->retval);
  405.     return 1;
  406. }
  407. #endif
  408.  
  409. /* Set up to catch interrupts */
  410. interrupt_setup()
  411. {
  412. #if defined (MSDOS) || defined(_Windows) || (defined (ATARI) && defined(__PUREC__)) || defined(DOS386)
  413. #ifdef __PUREC__
  414.     setmatherr(purec_matherr);
  415. #endif
  416. #if defined (__TURBOC__) || defined (__PUREC__)
  417. #if !defined(DOSX286) && !defined(BROKEN_SIGINT)
  418.         (void) signal(SIGINT, tc_interrupt);    /* go there on interrupt char */
  419. #endif
  420. #else
  421. #ifdef __ZTC__
  422.         (void) signal(SIGINT, ztc_interrupt);
  423. #else
  424. #ifdef __EMX__
  425.         (void) signal(SIGINT, (void *)inter);    /* go there on interrupt char */
  426. #else
  427. #ifdef DJGPP
  428.         (void) signal(SIGINT, (SignalHandler)inter);    /* go there on interrupt char */
  429. #else
  430.                (void) signal(SIGINT, inter);
  431. #endif
  432. #endif
  433. #endif
  434. #endif
  435. #else /* MSDOS */
  436.         (void) signal(SIGINT, inter);    /* go there on interrupt char */
  437. #endif /* MSDOS */
  438. }
  439.  
  440.  
  441. /* Look for a gnuplot start-up file */
  442. load_rcfile()
  443. {
  444.     register FILE *plotrc;
  445.     char home[80]; 
  446.     char rcfile[sizeof(PLOTRC)+80];
  447.  
  448.     /* Look for a gnuplot init file in . or home directory */
  449. #ifdef vms
  450.     (void) strcpy(home,HOME);
  451. #else /* vms */
  452.     char *tmp_home=getenv(HOME);
  453.     char *p;    /* points to last char in home path, or to \0, if none */
  454.     char c='\0';/* character that should be added, or \0, if none */
  455.  
  456.  
  457.     if(tmp_home) {
  458.         strcpy(home,tmp_home);
  459.     if( strlen(home) ) p = &home[strlen(home)-1];
  460.     else           p = home;
  461. #if defined(MSDOS) || defined(ATARI) || defined( OS2 ) || defined(_Windows) || defined(DOS386)
  462.     if( *p!='\\' && *p!='\0' ) c='\\';
  463. #else
  464. #if defined(AMIGA_AC_5)
  465.     if( *p!='/' && *p!=':' && *p!='\0' ) c='/';
  466. #else /* that leaves unix */
  467.     c='/';
  468. #endif
  469. #endif
  470.     if(c) {
  471.         if(*p) p++;
  472.         *p++=c;
  473.         *p='\0';
  474.     }
  475.     }
  476. #endif /* vms */
  477.  
  478. #ifdef NOCWDRC
  479.     /* inhibit check of init file in current directory for security reasons */
  480.     {
  481. #else
  482.     (void) strcpy(rcfile, PLOTRC);
  483.     plotrc = fopen(rcfile,"r");
  484.     if (plotrc == (FILE *)NULL) {
  485. #endif
  486. #ifndef vms
  487.     if( tmp_home ) {
  488. #endif
  489.        (void) sprintf(rcfile, "%s%s", home, PLOTRC);
  490.        plotrc = fopen(rcfile,"r");
  491. #ifndef vms
  492.     } else
  493.         plotrc=NULL;
  494. #endif
  495.     }
  496.     if (plotrc)
  497.      load_file(plotrc, rcfile);
  498. }
  499.